package com.hl.card.award.mq;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hl.card.award.service.IRewardByTrans;
import com.hl.card.common.mq.Mq4Base;
import com.hl.card.common.mq.QmCallback;
import com.hl.card.common.mq.RabbitConfigBase;
import com.hl.card.common.util.ResponseObject;
import com.hl.card.modular.pack.model.AwardReqModel;
import com.hl.card.modular.pack.model.AwardResult;
import com.rabbitmq.client.Channel;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import static com.hl.card.common.mq.RabbitConfigBase.*;

@Component
@Configuration
public class Mq4NotifyDemo extends Mq4Base implements QmCallback{
    String logPrefix = "【延时消息测试】";
    @Autowired
    private IRewardByTrans rewardByTrans;
    private static int count = 0;
//    /*
//    * 本方法可以一直发送6秒延时消息
//     */
//    @RabbitListener(queues= MqCustomConfig.QUEUE_COMMON_TEAT)
//    public void receive(Message message, Channel channel) throws IOException {
//        receivePayCenterMsg(message, channel);
//    }
//
//    /*
//* 监听回调
// */
//    @RabbitListener(queues= MqCustomConfig.QUEUE_COMMON_TEAT + RabbitConfigBase.CALL_BACK)
//    public void receiveCallback(Message message, Channel channel) throws IOException {
//        receivePayCenterMsg(message, channel);
//    }

    @RabbitListener(queues= MqCustomConfig.QUEUE_AWARD)
    public void receiveAwardMsg(Message message, Channel channel) throws IOException {
        //channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);//消息处理成功，删除队列中消息
        String msg = StringEscapeUtils.unescapeJson(new String(message.getBody()));
        System.out.println("接收消息队列奖励请求：" + msg);
        ResponseObject res =  new ResponseObject();
        Map map = new HashMap<>();
        res.setErroCode(1);
        String jsonStr = msg;
        if(msg.startsWith("\"")) {
            jsonStr = msg.substring(1,msg.length()-1);
        }
        JSONObject msgObj = null;
        try {
            msgObj = JSON.parseObject(jsonStr);
        } catch (Exception e) {
            e.printStackTrace();
            //send(MqCustomConfig.QUEUE_AWARD, msg, 3*1000);

            map.put("code", "" + AwardResult.INPUT_MSG_ERROR.getType());
            map.put("msg", AwardResult.INPUT_MSG_ERROR.getName());
            map.put("input", msg);
            map.put("detail", e.toString() + ":" + e.getStackTrace()[0].toString());
            res.setData(map);
            res.setErroCode(AwardResult.INPUT_MSG_ERROR.getType());
            send(MqCustomConfig.QUEUE_AWARD_MSG_ERROR, JSONObject.toJSONString(res));
            return;
        }
//        String function = msgObj.getString("function");
//        String communityAdmin = msgObj.getString("communityAdmin");
//        String recommender = msgObj.getString("recommender");
//        String userId = msgObj.getString("userId");
//        String amount = msgObj.getString("amount");

        System.out.println("接收消息队列奖励请求参数：" + msgObj.toJSONString());

        AwardReqModel awardReq = JSONObject.parseObject(jsonStr, AwardReqModel.class);
        try {
            if(awardReq != null) {
                switch (awardReq.getFunction()) {
                    case "doReward":
                        res = rewardByTrans.makeDistProfitSplitByCount(awardReq.getUserId(), awardReq.getProdCode(), awardReq.getAmount(), awardReq.getCount());
                        break;
                    case "doBatchReward":
                        res = rewardByTrans.makeDistProfitSplitByBatch(awardReq.getUserId(), awardReq.getProdCode(), awardReq.getAmount(), awardReq.getCount(), awardReq.getMchOrderNo());
                        break;
                    case "doWxCommunityReward":
                    case "makeCommunityAward":
                        res = rewardByTrans.makeDistProfitSplitByWxCommunity(awardReq.getCommunityAdmin(), awardReq.getRecommender(), awardReq.getUserId(), awardReq.getAmount());
                        break;
                    case "commonReward":
                        res = rewardByTrans.makeDistProfit(awardReq.getProdCode(), awardReq.getOrderId(), awardReq.getParentRecommender(), awardReq.getRecommender(), awardReq.getUserId(), awardReq.getAmount(), awardReq.getUnfreezeTime());
                        break;
                    case "makeAwardByCount":
                        res = rewardByTrans.makeAwardByCount(awardReq.getProdCode(), awardReq.getUserId(), awardReq.getAmount(), awardReq.getOrderId(), awardReq.getCount());
                        break;
                    case "makeAward":
                        res = rewardByTrans.makeAward(awardReq.getParentCode(), awardReq.getUserId(), awardReq.getAmount(), awardReq.getOrderId());
                        break;
                    case "makeAwardManualUnfreeze":
                        res = rewardByTrans.makeAward(awardReq.getParentCode(), awardReq.getUserId(), awardReq.getAmount(), awardReq.getOrderId(), awardReq.getUnfreezeTime());
                        break;
                    case "makeAdvanceAward":
                        res = rewardByTrans.makeAdvanceAward(awardReq.getParentCode(), awardReq.getRegCode(), awardReq.getUserId(), awardReq.getAmount(), awardReq.getOrderId());
                        break;
                    case "makeAdvanceAwardManualUnfreeze":
                        res = rewardByTrans.makeAdvanceAward(awardReq.getParentCode(), awardReq.getRegCode(), awardReq.getUserId(), awardReq.getAmount(), awardReq.getUserId(), awardReq.getUnfreezeTime());
                        break;
                    default:
                        res.setErroCode(AwardResult.NOT_SUPPORTED_FUNCTION.getType());
                        res.setData(AwardResult.NOT_SUPPORTED_FUNCTION.getName());
                        break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            map.put("mchOrderNo", awardReq.getOrderId());
            map.put("code", "" + AwardResult.AWARD_INNER_ERROR.getType());
            map.put("msg", AwardResult.AWARD_INNER_ERROR.getName());
            map.put("detail", e.toString() + ":" + e.getStackTrace()[0].toString());
            res.setData(map);
            res.setErroCode(AwardResult.AWARD_INNER_ERROR.getType());
            if(StringUtils.isNotBlank(awardReq.getQueueName())) {
                send(awardReq.getQueueName(), JSONObject.toJSONString(res));
            }else {
                send(MqCustomConfig.QUEUE_AWARD + RabbitConfigBase.CALL_BACK, JSONObject.toJSONString(res));
            }
            return;
        }
        Map data = (Map) res.getData();
        data.put("mchOrderNo", awardReq.getOrderId());
        if (res.getErroCode() == 0) {
            System.out.println("奖励转账成功");
        } else {
            if (data != null) {
                String code = (String) data.get("code");
                if ("11".equals(code)) {//支付中心无响应，可能是网络问题，进入补偿队列流程
                    String retryStr = msgObj.getString("retry");
                    int retry = 1;
                    if(StringUtils.isNotBlank(retryStr)) {
                        retry += Integer.parseInt(retryStr);
                    }
                    if(retry > 8)
                    msgObj.put("retry", Integer.toString(retry));
                    send(MqCustomConfig.QUEUE_AWARD, msgObj.toJSONString(), retry*10*60*1000);
                    System.out.println("奖励转账失败，可能是网络问题，进行重试:" + retry);
                    //通过异步消息将奖励结果返回给发送方
                    data.put("retry", retry);
                }
                res.setErroCode(Integer.parseInt(code));
            }
        }
        if(StringUtils.isNotBlank(awardReq.getQueueName())) {
            send(awardReq.getQueueName(), JSONObject.toJSONString(res));
        }else {
            send(MqCustomConfig.QUEUE_AWARD + RabbitConfigBase.CALL_BACK, JSONObject.toJSONString(res));
        }
    }

//    @RabbitListener(queues= MqCustomConfig.QUEUE_AWARD + RabbitConfigBase.CALL_BACK)
//    public void receiveAwardCallbackMsg(Message message, Channel channel) throws IOException {
//        //channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);//消息处理成功，删除队列中消息
//        String msg = StringEscapeUtils.unescapeJson(new String(message.getBody()));
//        System.out.println("接收消息队列回调奖励请求：" + msg);
//        String jsonStr = msg;
//        if(msg.startsWith("\"")) {
//            jsonStr = msg.substring(1,msg.length()-1);
//        }
//        JSONObject msgObj;
//        try {
//            msgObj = JSON.parseObject(jsonStr);
//        } catch (Exception e) {
//            e.printStackTrace();
//            //send(MqCustomConfig.QUEUE_AWARD, msg, 3*1000);
//            return;
//        }
//        System.out.println("奖励结果：" + msgObj.toJSONString());
//    }

    @RabbitListener(queues= MqCustomConfig.PAY_NOTIFY_QUEUE)
    public void receivePayCenterMsg(Message message, Channel channel) throws IOException {
        //channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);//消息处理成功，删除队列中消息
        String msg = StringEscapeUtils.unescapeJson(new String(message.getBody()));
        System.out.println("接收消息队列奖励请求：" + msg);
        String jsonStr = msg.substring(1,msg.length()-1);
        JSONObject msgObj = JSON.parseObject(jsonStr);
        String userId = msgObj.getString("user_id");
        String begin_time = msgObj.getString("begin_time");
        String code = msgObj.getString("code");
        String mchOrderNo = msgObj.getString("mchOrderNo");
        String amount = msgObj.getString("amount");
        String orderType = msgObj.getString("type");
        System.out.println("接收消息队列奖励请求参数：" + msgObj.toJSONString());
        if("T".equals(code) || "H".equals(code) || "L".equals(code) || "C".equals(code) || "O".equals(code)) {
            ResponseObject res = rewardByTrans.makeDistProfitSplitByTrans(userId, code, amount, "fen", orderType, 1, mchOrderNo, begin_time);
            Map data = (Map) res.getData();
            if (res.getErroCode() == 0) {
                System.out.println("奖励转账成功");
                //channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);//消息处理成功，删除队列中消息
            } else {
                if (data != null) {
                    if ("10".equals(data.get("code"))) {//重复领奖
                        //channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);//消息处理成功，删除队列中消息
                    }else {
                        super.send(MqCustomConfig.PAY_NOTIFY_QUEUE, jsonStr, 5 * 60 * 1000);
                    }
                }else {
                    super.send(MqCustomConfig.PAY_NOTIFY_QUEUE, jsonStr, 5 * 60 * 1000);
                }
            }
            //super.send(MqCustomConfig.QUEUE_COMMON_TEAT, msgObj.toJSONString());
        }else if("CWHHR".equals(code)){
            ResponseObject res = rewardByTrans.makeAward(code, userId, amount, mchOrderNo);
            Map data = (Map) res.getData();
            if (res.getErroCode() == 0) {
                System.out.println("奖励转账成功");
                //channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);//消息处理成功，删除队列中消息
            } else {
                if (data != null) {
                    if ("10".equals(data.get("code"))) {//重复领奖
                        //channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);//消息处理成功，删除队列中消息
                    }else {
                        super.send(MqCustomConfig.PAY_NOTIFY_QUEUE, jsonStr, 5 * 60 * 1000);
                    }
                }else {
                    super.send(MqCustomConfig.PAY_NOTIFY_QUEUE, jsonStr, 5 * 60 * 1000);
                }
            }
        }else {
            //channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);//消息处理成功，删除队列中消息
        }
    }

    public void send(String queue_name, String msg) {
        super.send(queue_name, msg);
    }

    public void send(String queue_name, String msg, long delay) {
        super.send(queue_name, msg, delay);
    }

    @Override
    public void OnPickup(String queue_name, String msg) {

    }
}